﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RadPaneGroupRegionAdapter.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the <seealso cref="RadPaneGroupRegionAdapter" /> type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Common.Adapters
{
    using System.Collections.Specialized;
    using System.Linq;
    using System.Windows.Controls;

    using Microsoft.Practices.Prism.Regions;

    using Telerik.Windows.Controls;

    /// <summary>
    /// Defines the <seealso cref="RadPaneGroupRegionAdapter"/> type.
    /// </summary>
    public class RadPaneGroupRegionAdapter : RegionAdapterBase<RadPaneGroup>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RadPaneGroupRegionAdapter"/> class.
        /// </summary>
        /// <param name="regionBehaviorFactory">The region behavior factory.</param>
        public RadPaneGroupRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            : base(regionBehaviorFactory)
        {
        }

        /// <summary>
        /// Adapts the specified region.
        /// </summary>
        /// <param name="region">The region.</param>
        /// <param name="regionTarget">The region target.</param>
        protected override void Adapt(IRegion region, RadPaneGroup regionTarget)
        {
            region.Views.CollectionChanged += (s, e) =>
            {
                switch (e.Action)
                {
                    case NotifyCollectionChangedAction.Add:
                        foreach (var item in e.NewItems.OfType<RadPane>())
                        {
                            regionTarget.Items.Add(item);
                        }

                        break;
                    case NotifyCollectionChangedAction.Remove:
                        foreach (var item in e.OldItems.OfType<RadPane>())
                        {
                            item.RemoveFromParent();
                        }

                        break;
                    case NotifyCollectionChangedAction.Replace:
                        var oldItems = e.OldItems.OfType<RadPane>();
                        var newItems = e.NewItems.OfType<RadPane>();
                        var newItemsEnumerator = newItems.GetEnumerator();
                        foreach (var oldItem in oldItems)
                        {
                            var parent = oldItem.Parent as ItemsControl;
                            if (parent != null && parent.Items.Contains(oldItem))
                            {
                                parent.Items[parent.Items.IndexOf(oldItem)] = newItemsEnumerator.Current;
                                if (!newItemsEnumerator.MoveNext())
                                {
                                    break;
                                }
                            }
                            else
                            {
                                oldItem.RemoveFromParent();
                                regionTarget.Items.Add(newItemsEnumerator.Current);
                            }
                        }

                        break;
                    case NotifyCollectionChangedAction.Reset:
                        regionTarget
                            .EnumeratePanes()
                            .ToList()
                            .ForEach(p => p.RemoveFromParent());
                        break;
                    default:
                        break;
                }
            };

            foreach (var view in region.Views.OfType<RadPane>())
            {
                regionTarget.Items.Add(view);
            }
        }

        /// <summary>
        /// Creates the region.
        /// </summary>
        /// <returns>Region object</returns>
        protected override IRegion CreateRegion()
        {
            return new AllActiveRegion();
        }
    }
}